/*
 * Copyright 2011 group coding kata nantes
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package fr.coding.kata.nantes.countwords.sylvain;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * 
 * @author Sylvain Leduby
 * @since 1.0
 */
public class CountWordUtil {

    /** Logger. */
    private static final Logger LOG = LoggerFactory.getLogger(CountWordUtil.class);

    private CountWordUtil() {
        super();
    }

    /**
     * <p>
     * Joins the elements of the provided array into a single String containing the provided list of
     * elements.
     * </p>
     * 
     * <p>
     * No delimiter is added before or after the list. Null objects or empty strings within the
     * array are represented by empty strings.
     * </p>
     * 
     * <p>
     * The separator used is the space ' '.
     * </p>
     * 
     * <pre>
     * StringUtils.join(null)               = null
     * StringUtils.join([null])             = ""
     * StringUtils.join(["a", "b", "c"])    = "a b c"
     * StringUtils.join([null, "", "a"])    = "  a"
     * </pre>
     * 
     * @param array the array of values to join together, may be null
     * @return the joined String, <code>null</code> if null array input
     * @see StringUtils#join(Object[], char)
     */
    public static String join(final String... strings) {
        final String joinedString = StringUtils.join(strings, ' ');
        LOG.debug(joinedString);
        return joinedString;
    }

    /**
     * <p>
     * Generate a random string containing the provided number of occurrences of the given word
     * mixed with any number of randomly generated words.
     * </p>
     * 
     * <p>
     * It ensure the provided word is never added accidentally.
     * </p>
     * 
     * @param word Reference word to repeat.
     * @param occurences The number of time the word should be repeated.
     * @return a string containing the provided number of occurrences of the given word mixed with
     *         any number of randomly generated words.
     */
    public static String generate(final String word, final int occurrences) {
        LOG.debug("Generate a string with {} occurrences of {}", occurrences, word);

        final List<String> parts = new ArrayList<String>();

        for (int i = 0; i < occurrences; i++) {
            addWords(parts).add(word);
        }
        addWords(parts);

        return join(parts.toArray(new String[parts.size()]));
    }

    private static List<String> addWords(final List<String> parts) {
        final int count = generateRandomInteger();
        for (int j = 0; j < count; j++) {
            parts.add(generateRandomWord());
        }
        return parts;
    }

    public static String generateRandomWord() {
        return RandomStringUtils.randomAlphabetic(generateRandomIntegerStrict());
    }

    public static int generateRandomInteger() {
        return generateRandomInteger(0);
    }

    /**
     * The integer is strictly greater than 0.
     * 
     * @return A positive integer greater than 0.
     */
    public static int generateRandomIntegerStrict() {
        return generateRandomInteger(1);
    }

    public static int generateRandomInteger(final int min) {
        return min + (int) (Math.random() * 100);
    }

}
